#include "capfilewin32.h"


CapFileWin32::CapFileWin32()
{
	fileinfosize_ = sizeof(struct _wfinddata_t);
	for (int i = 0; i < PRE_BUF_NUM; i++) {
		ifilepack_[i].buf = new char[PRE_BUF_SIZE];
		isignal_[i].Init();
	}
}

CapFileWin32::~CapFileWin32()
{
	CaptorStop();

	for (int i = 0; i < PRE_BUF_NUM; i++) {
		delete []ifilepack_[i].buf;
		isignal_[i].Destroy();
	}
}

int CapFileWin32::CaptorInit()
{
	return 1;
}

int CapFileWin32::CaptorStart()
{
	usingbufnum_ = 0;
	bstarted_ = true;
	return 1;
}

int CapFileWin32::CaptorStop()
{
	bstarted_ = false;
	return 1;
}

int CapFileWin32::CaptorSubDir(wstring path)
{
	unsigned char buf_num_ = 0;
	isignal_[buf_num_].Wait();
	memset(&ifilepack_[buf_num_], 0, sizeof(IFilePackHeader));
	
	struct _wfinddata_t wfd;
	intptr_t handle = _wfindfirst(path.c_str(), &wfd);
	if(handle == -1)  return -1;

	memmove(ifilepack_[buf_num_].buf + ifilepack_[buf_num_].hdr.size, &wfd, fileinfosize_);
	ifilepack_[buf_num_].hdr.numb++;
	ifilepack_[buf_num_].hdr.size+=fileinfosize_;

	while (!_wfindnext(handle, &wfd)){
		memmove(ifilepack_[buf_num_].buf + ifilepack_[buf_num_].hdr.size, &wfd, fileinfosize_);
		ifilepack_[buf_num_].hdr.numb++;
		ifilepack_[buf_num_].hdr.size+=fileinfosize_;

		if(ifilepack_[buf_num_].hdr.size >= PRE_BUF_SIZE - fileinfosize_) {
			// post 
			isignal_[buf_num_].Signal();

			// reset header
			buf_num_ ^= 1;
			isignal_[buf_num_].Wait();
			memset(&ifilepack_[buf_num_], 0, sizeof(IFilePackHeader));
		}
	}

	_findclose(handle);
	isignal_[buf_num_].Signal();
	return 1;
}

int CapFileWin32::CaptorFile(wstring filename)
{
	unsigned char buf_num_ = 0;
	isignal_[buf_num_].Wait();
	memset(&ifilepack_[buf_num_], 0, sizeof(IFilePackHeader));
	ifilepack_[buf_num_].hdr.type = 1;

	FILE* fd = NULL;
	if(0 != _wfopen_s(&fd, filename.c_str(), L"rb"))
		return 0;

	while(bstarted_ &&
		(ifilepack_[buf_num_].hdr.size = 
		(unsigned short)fread(ifilepack_[buf_num_].buf, sizeof(char), PRE_BUF_SIZE, fd))) {

		isignal_[buf_num_].Signal();

		// reset header
		buf_num_ ^= 1;
		isignal_[buf_num_].Wait();
		memset(&ifilepack_[buf_num_], 0, sizeof(IFilePackHeader));
		ifilepack_[buf_num_].hdr.type = 1;
	}

	fclose(fd);
	isignal_[buf_num_].Signal();
	return 1;
}

int CapFileWin32::GetCaptorData(void* data)
{
	unsigned int datasize = 0;

	if(isignal_[usingbufnum_].Wait(10 * 1000)){
		datasize = sizeof(IFilePackHeader) + ifilepack_[usingbufnum_].hdr.size;
		memmove(data, &ifilepack_[usingbufnum_], datasize);
		isignal_[usingbufnum_].Signal();
		usingbufnum_ ^= 1;
	}
	return datasize;
}